package system

import (
	"context"
	"encoding/json"
	"fmt"
	"gf-assistant/internal/common/consts"
	"gf-assistant/internal/common/factory"
	"gf-assistant/internal/system/parameter"
	"github.com/gogf/gf/v2/util/gconv"
	"reflect"

	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
)

type RoleDao struct{}

func init() {
	roleDao := RoleDao{}
	factory.Put(reflect.TypeOf(roleDao).String(), &roleDao)
}

// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *RoleDao) DB() gdb.DB {
	return g.DB()
}
func (dao *RoleDao) ListRole(ctx context.Context, req *parameter.ListRoleReq) (roles []*parameter.GetRoleRes) {

	sql := `
		  select t.ROLE_ID as RoleId,t.ROLE_NAME as RoleName,t.REMARK as Remark,
		         t.ENABLE_STATUS as EnableStatus ,ELT(FIELD(t.ENABLE_STATUS, 0, 1),'无效','有效')AS EnableStatusName,
		         c.NICK_NAME as CreatedUserName,p.NICK_NAME as UpdatedUserName,
				 DATE_FORMAT(t.CREATE_TIME,'%Y-%m-%d %T') as CreatedTime,
				 DATE_FORMAT(t.UPDATE_TIME,'%Y-%m-%d %T') as UpdatedTime
		  from SYS_ROLE t 
		  left join SYS_USER c on t.CREATE_USER=c.USER_ID
		  left join SYS_USER p on t.UPDATE_USER=p.USER_ID
		  `
	where := consts.WHERE
	if req.RoleName != "" {
		where = where + " and t.ROLE_NAME like '%" + req.RoleName + "%'\n"
	}
	if req.EnableStatus > -1 {
		where = where + " and t.ENABLE_STATUS=" + gconv.String(req.EnableStatus) + "\n"
	}
	if where != consts.WHERE {
		sql = sql + where
	}
	sql = sql + " order by t.ENABLE_STATUS desc, t.UPDATE_TIME DESC \n"
	sql = sql + " limit " + gconv.String((req.Page-1)*req.Size) + "," + gconv.String(req.Size)
	resultList, err := g.DB().GetAll(ctx, sql)
	if err != nil {
		fmt.Printf("query faied, error:[%v]", err.Error())
		return
	}
	//遍历结构体切片
	for _, v := range resultList {
		role := parameter.GetRoleRes{}
		err = json.Unmarshal([]byte(v.Json()), &role)
		if err != nil {
			fmt.Println("JSON unmarshal error:", err)
		}
		roles = append(roles, &role)
	}
	return roles
}
func (dao *RoleDao) CountRole(ctx context.Context, req *parameter.ListRoleReq) (count int64) {
	sql := `
		  select count(t.ROLE_ID) cnt
		  from SYS_ROLE t 
		  `
	where := consts.WHERE
	if req.RoleName != "" {
		where = where + " and t.ROLE_NAME like '%" + req.RoleName + "%'\n"
	}
	if req.EnableStatus > -1 {
		where = where + " and t.ENABLE_STATUS=" + gconv.String(req.EnableStatus) + "\n"
	}
	if where != consts.WHERE {
		sql = sql + where
	}
	one, err := g.DB().GetOne(ctx, sql)
	if err != nil {
		fmt.Printf("query faied, error:[%v]", err.Error())
		return
	}
	count = gconv.Int64(one.Map()["cnt"])
	return count
}
func (dao *RoleDao) SaveRoleMenu(tx gdb.TX, roleId uint, menuIds []uint, operatorId uint) {
	sql := `
			update SYS_ROLE_MENU set 
				ENABLE_STATUS=0,
				UPDATE_TIME=now(),
				UPDATE_USER=?
			where ROLE_ID=?
		  `
	_, err := tx.Exec(sql, operatorId, roleId)
	if err != nil {
		fmt.Printf("insert role faied, error:[%v]", err.Error())
	}
	sql = `
		insert into SYS_ROLE_MENU(ROLE_ID,MENU_ID,ENABLE_STATUS,CREATE_TIME,CREATE_USER,UPDATE_TIME,UPDATE_USER)
		values (?,?,1,now(),?,now(),?)
		on duplicate key update 
			ENABLE_STATUS=1,
			UPDATE_TIME=now(),
			UPDATE_USER=?
	  `
	for _, v := range menuIds {
		_, err = tx.Exec(sql, roleId, v, operatorId, operatorId, operatorId)
		if err != nil {
			fmt.Printf("insert role-menu faied, error:[%v]", err.Error())
		}
	}
}
func (dao *RoleDao) SaveRole(tx gdb.TX, req *parameter.SaveRoleReq) (res *parameter.SaveRoleRes) {
	sql := `
			insert into SYS_ROLE(ROLE_NAME,REMARK,ENABLE_STATUS,CREATE_TIME,CREATE_USER,UPDATE_TIME,UPDATE_USER)
			values (?,?,1,now(),?,now(),?)
			on duplicate key update 
				REMARK=?,
				ENABLE_STATUS=1,
				UPDATE_TIME=now(),
				UPDATE_USER=?
		  `
	result, err := tx.Exec(sql, req.RoleName, req.Remark, req.GetOperatorId(), req.GetOperatorId(),
		req.Remark, req.GetOperatorId())
	if err != nil {
		fmt.Printf("insert role faied, error:[%v]", err.Error())
		return nil
	}
	insertId, _ := result.LastInsertId()
	return &parameter.SaveRoleRes{RoleId: gconv.Uint(insertId)}
}

func (dao *RoleDao) DeleteRole(tx gdb.TX, req *parameter.DeleteRoleReq) {
	parameters := make([]interface{}, 0)
	sql := `
			update SYS_ROLE set 
				ENABLE_STATUS=0,
				UPDATE_TIME=now(),
				UPDATE_USER=?
			where ROLE_ID=?
		  `
	parameters = append(parameters, req.GetOperatorId(), req.RoleId)
	_, err := tx.Exec(sql, parameters)
	if err != nil {
		fmt.Printf("update user faied, error:[%v]", err.Error())
	}
}
